package cn.com.dhcc.turbo.service.exch.filedata.validator;

import java.io.File;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

import cn.com.dhcc.app.core.exception.NiceException;
import cn.com.dhcc.app.core.exception.ServiceException;
import cn.com.dhcc.app.core.service.Log;
import cn.com.dhcc.app.core.service.Log.LOGTYPE;
import cn.com.dhcc.app.core.util.CollectionUtil;
import cn.com.dhcc.app.core.util.Status;
import cn.com.dhcc.app.core.util.StrUtil;
import cn.com.dhcc.app.core.util.XstreamUtil;
import cn.com.dhcc.app.pub.core.consts.AppConst;
import cn.com.dhcc.app.pub.core.consts.AppIocBean;
import cn.com.dhcc.app.pub.core.consts.NodeInfoParam;
import cn.com.dhcc.app.pub.core.tag.AppTagEl;
import cn.com.dhcc.turbo.entity.api.Posthead;
import cn.com.dhcc.turbo.entity.api.RouteEntry;
import cn.com.dhcc.turbo.entity.registry.AdapterInfo;
import cn.com.dhcc.turbo.entity.registry.NodeInfo;
import cn.com.dhcc.turbo.service.registry.AdapterInfoService;
import cn.com.dhcc.turbo.service.registry.BaseInfoService;

/**
 * 大文件数据posthead验证器
 */
@Service
public class FileDataPostheadValidator implements FileDataMessageValidator {
    @SuppressWarnings("deprecation")
	private static Logger logger = Log.getDetachLogger(LOGTYPE.TURBO);
    //用户上传到ftp服务器的文件目录。该目录是相对目录,存在用户自身目录下
//    private static final String uploadmetadataDir = AppEnv.ParaGetTool.getPara("filedata.uploadmetadata.dir");


	@Autowired
    private AdapterInfoService adapterInfoService;
	@Autowired
	@Qualifier(AppIocBean.BASE_INFO_SERVICEIMPL_BEAN)
	private BaseInfoService baseInfoService;
	
	


    /**
     * 校验posthead
     *
     * @param filexml
     * @return
     */
    @Override
    public Status validate(File filexml) {
        String msg;
        String uploadmetadataPath = new File(new File(filexml.getParent()).getParent(), AppConst.FILEDATA_UPLOADMETADATA_DIR).getPath();
        String filename = filexml.getName();//获取文件名
        try {
            Posthead posthead =XstreamUtil.toObject(Posthead.class,filexml);
            return validate(filename, uploadmetadataPath, posthead);
        } catch (Exception e) {
            Status status = Status.getInstance();
            msg = "解析posthead头信息出错:" + filexml + ">>>cause:" + e.fillInStackTrace();
            logger.error(msg, e);
            status.setSuccess(false);
            status.setMsg(msg);
            status.setData("-1");
            return status;
        }
    }

    @Override
    public Status validate(String uploadmetadataPath, String filepostheadxml) {
        String msg;
        Status status = Status.getInstance();
        try {
            if (StrUtil.isBlank(filepostheadxml)) {
                msg = "posthead参数不能为空";
                status.setSuccess(false);
                status.setMsg(msg);
                status.setData("-1");
                return status;
            }
            Posthead posthead = XstreamUtil.toObject(Posthead.class,filepostheadxml);
            return validate(null, uploadmetadataPath, posthead);
        } catch (Exception e) {
            msg = "解析posthead头信息出错:" + filepostheadxml + ">>>cause:" + e.fillInStackTrace();
            logger.error(msg, e);
            status.setSuccess(false);
            status.setMsg(msg);
            status.setData("-1");
            return status;
        }
    }

    private Status validate(String filename, String uploadmetadataPath, Posthead posthead) throws NiceException, ServiceException {
        String msg;
        Status status = Status.getInstance();
        status.setData("-1");
        
        NodeInfo localNode=baseInfoService.getCurrentNodeInfo();
        if (localNode==null) {
			msg = "节点还未完成初始化，请稍后再发送数据..";
			status.setSuccess(false);
			status.setMsg(msg);
			return status;
		}
        
      //验证头信息
		if (posthead == null) {
			msg = "解析pohsthead头信息出错";
			status.setSuccess(false);
			status.setMsg(msg);
			return status;
		}
		
		//from非空验证
		if (posthead.getFrom() == null) {
			msg = "解析pohsthead头信息出错，发送信息posthead/from不能为空";
			status.setSuccess(false);
			status.setMsg(msg);
			return status;
		}
		//from/nodecode非空验证
		if (StrUtil.isBlank(posthead.getFrom().getNodecode())) {
			msg = "解析pohsthead头信息出错，发送头信息中posthead/from/nodecode参数不能为空";
			status.setSuccess(false);
			status.setMsg(msg);
			return status;
		}
	
		
		//from/Adaptorcode非空验证
		if (posthead.getFrom().getAdaptorcode() == null) {
			msg = "解析pohsthead头信息出错，数据类型posthead/from/adaptorcode不能为空";
			status.setSuccess(false);
			status.setMsg(msg);
			return status;
		}
		
       //to非空验证
		if (!CollectionUtil.hasElement(posthead.getToList())) {
			msg = "解析pohsthead头信息出错，接收信息posthead/to不能为空";
			status.setSuccess(false);
			status.setMsg(msg);
			return status;
		}
		//to/nodecode非空验证
		for (RouteEntry to : posthead.getToList()) {
			if (StrUtil.isBlank(to.getNodecode())) {
				msg = "解析pohsthead头信息出错，接收信息中posthead/to/nodecode参数不能为空";
				status.setSuccess(false);
				status.setMsg(msg);
				return status;
			}
			
			
			if (to.getNodecode().length()!=posthead.getFrom().getNodecode().length()) {
				msg = "解析pohsthead头信息出错，接收信息中posthead/to/nodecode参数格式不正确";
				status.setSuccess(false);
				status.setMsg(msg);
				return status;
			}
		}
		
	
		
		//attachments非空验证
		if (posthead.getAttachments()==null) {
			msg = "解析pohsthead头信息出错，发送头信息中posthead/attachments参数不能为空";
			status.setSuccess(false);
			status.setMsg(msg);
			return status;
		}
		//attachment非空验证
		if (posthead.getAttachments().getAttachment()==null || posthead.getAttachments().getAttachment().isEmpty()) {
			msg = "解析pohsthead头信息出错，发送头信息中posthead/attachments/attachment参数不能为空";
			status.setSuccess(false);
			status.setMsg(msg);
			return status;
		}
		
		//attachment非空验证
		boolean flag=false;
		for (String att : posthead.getAttachments().getAttachment()) {
			if (att!=null && !att.trim().equals("")) {
				flag=true;
				break;
			}
		}
		if (!flag) {
			msg = "解析pohsthead头信息出错，发送头信息中posthead/attachments/attachment没有包含文件信息";
			status.setSuccess(false);
			status.setMsg(msg);
			return status;
		}
		
	
		
		//校验适配器
		AdapterInfo adapterInfo=adapterInfoService.getAdapterInfo(posthead.getFrom().getNodecode(), posthead.getFrom().getAdaptorcode());
		if (adapterInfo==null) {
			msg = "校验pohsthead头信息失败，发送适配器["+posthead.getFrom().getAdaptorcode()+"]未注册";
			status.setSuccess(false);
			status.setMsg(msg);
			return status;
		}
		
		
		NodeInfo nodeInfo=baseInfoService.getNodeInfoByCode(posthead.getFrom().getNodecode());
		if (nodeInfo==null) {
			msg = "校验pohsthead头信息失败，发送系统["+posthead.getFrom().getNodecode()+"]未在平台注册";
			status.setSuccess(false);
			status.setMsg(msg);
			return status;
		}
		if (!nodeInfo.getNodeCode().equals(localNode.getNodeCode())) {
			msg = "校验pohsthead头信息失败，发送节点["+posthead.getFrom().getNodecode()+"]不是当前节点";
			status.setSuccess(false);
			status.setMsg(msg);
			return status;
		}
		
		//如果能查到nodecode说明，非跨网传输，否则跨网传输
		for (int i=0;i<posthead.getToList().size();i++) {
			RouteEntry to = posthead.getToList().get(i);
			if (posthead.getFrom().getNodecode().substring(6, 7).equals(to.getNodecode().substring(6, 7))) {//同网段的必须判断接收节点也存在
				NodeInfo toNodeInfo=baseInfoService.getNodeInfoByCode(to.getNodecode());
				if (toNodeInfo==null) {
					msg = "校验pohsthead头信息失败，接收节点["+to.getNodecode()+"]未在平台注册";
					status.setSuccess(false);
					status.setMsg(msg);
					return status;
				}
				
				//判断接收适配器是否存在：
				AdapterInfo info=baseInfoService.getAdapterInfo(to.getNodecode(), adapterInfo.getAdapterCode());
				if (info==null) {
					msg = "校验pohsthead头信息失败，接收节点["+to.getNodecode()+"]未绑定适配器["+adapterInfo.getAdapterCode()+"],请通知接收方绑定该适配器";
					status.setSuccess(false);
					status.setMsg(msg);
					return status;
				}
			}
		}
        
		
		//判断是否是内网到外网传输
		if (NodeInfoParam.isInnerNode()) {//from 节点时内网
			
			flag=false;
			for (RouteEntry to : posthead.getToList()) {
				if (!AppTagEl.isInnerNet(to.getNodecode().substring(6, 7))) {//如果to为外网
					flag=true;
					break;
				}
			}
			if (flag) {//如果有内网到外网
				//from/auditor非空验证
				if (StrUtil.isBlank(posthead.getFrom().getAuditor())) {
					msg = "解析pohsthead头信息出错，发送头信息中posthead/auditor参数不能为空";
					status.setSuccess(false);
					status.setMsg(msg);
					return status;
				}
			}
		}
		
       
        msg = "校验成功";
        status.setSuccess(true);
        status.setMsg(msg);
        status.setData(posthead);
        return status;

    }
}
